home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / shockab.zip / COMBAT.QC < prev    next >
Text File  |  1996-10-11  |  7KB  |  313 lines

  1.  
  2. void() T_MissileTouch;
  3. void() info_player_start;
  4. void(entity targ, entity attacker) ClientObituary;
  5.  
  6. void() monster_death_use;
  7.  
  8. //============================================================================
  9.  
  10. /*
  11. ============
  12. CanDamage
  13.  
  14. Returns true if the inflictor can directly damage the target.  Used for
  15. explosions and melee attacks.
  16. ============
  17. */
  18. float(entity targ, entity inflictor) CanDamage =
  19. {
  20. // bmodels need special checking because their origin is 0,0,0
  21.     if (targ.movetype == MOVETYPE_PUSH)
  22.     {
  23.         traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
  24.         if (trace_fraction == 1)
  25.             return TRUE;
  26.         if (trace_ent == targ)
  27.             return TRUE;
  28.         return FALSE;
  29.     }
  30.     
  31.     traceline(inflictor.origin, targ.origin, TRUE, self);
  32.     if (trace_fraction == 1)
  33.         return TRUE;
  34.     traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
  35.     if (trace_fraction == 1)
  36.         return TRUE;
  37.     traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
  38.     if (trace_fraction == 1)
  39.         return TRUE;
  40.     traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
  41.     if (trace_fraction == 1)
  42.         return TRUE;
  43.     traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
  44.     if (trace_fraction == 1)
  45.         return TRUE;
  46.  
  47.     return FALSE;
  48. };
  49.  
  50.  
  51. /*
  52. ============
  53. Killed
  54. ============
  55. */
  56. void(entity targ, entity attacker) Killed =
  57. {
  58.     local entity oself;
  59.  
  60.     oself = self;
  61.     self = targ;
  62.     
  63.     if (self.health < -99)
  64.         self.health = -99;            // don't let sbar look bad if a player
  65.  
  66.     if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  67.     {     // doors, triggers, etc
  68.         self.th_die ();
  69.         self = oself;
  70.         return;
  71.     }
  72.  
  73.     self.enemy = attacker;
  74.  
  75. // bump the monster counter
  76.     if (self.flags & FL_MONSTER)
  77.     {
  78.         killed_monsters = killed_monsters + 1;
  79.         WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
  80.     }
  81.  
  82.     ClientObituary(self, attacker);
  83.     
  84.     self.takedamage = DAMAGE_NO;
  85.     self.touch = SUB_Null;
  86.  
  87.     monster_death_use();
  88.     self.th_die ();
  89.     
  90.     self = oself;
  91. };
  92.  
  93.  
  94. /*
  95. ============
  96. T_Damage
  97.  
  98. The damage is coming from inflictor, but get mad at attacker
  99. This should be the only function that ever reduces health.
  100. ============
  101. */
  102. void(entity targ, entity attacker, float damage) S_Damage =
  103. {
  104.     if (!targ.takedamage)
  105.         return;
  106.  
  107.     if (targ.flags & FL_GODMODE)
  108.         return;
  109.     
  110.     if (targ.invincible_finished >= time)
  111.     {
  112.         if (self.invincible_sound < time)
  113.         {
  114.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  115.             self.invincible_sound = time + 2;
  116.         }
  117.         return;
  118.     }
  119.  
  120.     targ.health = targ.health - damage;
  121.             
  122.     if (targ.health <= 0)
  123.     {
  124.         Killed (targ, targ.enemy);
  125.         return;
  126.     }
  127. };
  128.  
  129. void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
  130. {
  131.     local vector      dir;
  132.     local entity      oldself;
  133.     local float save;
  134.     local float take;
  135.  
  136.     if (!targ.takedamage)
  137.         return;
  138.  
  139. // used by buttons and triggers to set activator for target firing
  140.     damage_attacker = attacker;
  141.  
  142. // check for quad damage powerup on the attacker
  143.     if (attacker.super_damage_finished > time)
  144.         damage = damage * 4;
  145.  
  146. // save damage based on the target's armor level
  147.  
  148.     save = ceil(targ.armortype*damage);
  149.     if (save >= targ.armorvalue)
  150.     {
  151.         save = targ.armorvalue;
  152.         targ.armortype = 0;     // lost all armor
  153.         targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
  154.     }
  155.     
  156.     targ.armorvalue = targ.armorvalue - save;
  157.     take = ceil(damage-save);
  158.  
  159. // add to the damage total for clients, which will be sent as a single
  160. // message at the end of the frame
  161. // FIXME: remove after combining shotgun blasts?
  162.     if (targ.flags & FL_CLIENT)
  163.     {
  164.         targ.dmg_take = targ.dmg_take + take;
  165.         targ.dmg_save = targ.dmg_save + save;
  166.         targ.dmg_inflictor = inflictor;
  167.     }
  168.  
  169. // figure momentum add
  170.     if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  171.     {
  172.         dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  173.         dir = normalize(dir);
  174.         targ.velocity = targ.velocity + dir*damage*8;
  175.     }
  176.  
  177. // check for godmode or invincibility
  178.     if (targ.flags & FL_GODMODE)
  179.         return;
  180.     if (targ.invincible_finished >= time)
  181.     {
  182.         if (self.invincible_sound < time)
  183.         {
  184.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  185.             self.invincible_sound = time + 2;
  186.         }
  187.         return;
  188.     }
  189.  
  190. // team play damage avoidance
  191.     if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
  192.         return;
  193.         
  194. // do the damage
  195.     targ.health = targ.health - take;
  196.             
  197.     if (targ.health <= 0)
  198.     {
  199.         Killed (targ, attacker);
  200.         return;
  201.     }
  202.  
  203. // react to the damage
  204.     oldself = self;
  205.     self = targ;
  206.  
  207.     if ( (self.flags & FL_MONSTER) && attacker != world)
  208.     {
  209.     // get mad unless of the same class (except for soldiers)
  210.         if (self != attacker && attacker != self.enemy)
  211.         {
  212.             if ( (self.classname != attacker.classname) 
  213.             || (self.classname == "monster_army" ) )
  214.             {
  215.                 if (self.enemy.classname == "player")
  216.                     self.oldenemy = self.enemy;
  217.                 self.enemy = attacker;
  218.                 FoundTarget ();
  219.             }
  220.         }
  221.     }
  222.  
  223.     if (self.th_pain)
  224.     {
  225.         self.th_pain (attacker, take);
  226.     // nightmare mode monsters don't go into pain frames often
  227.         if (skill == 3)
  228.             self.pain_finished = time + 5;            
  229.     }
  230.  
  231.     self = oldself;
  232. };
  233.  
  234. /*
  235. ============
  236. T_RadiusDamage
  237. ============
  238. */
  239. void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
  240. {
  241.     local float       points;
  242.     local entity      head;
  243.     local vector      org;
  244.  
  245.     head = findradius(inflictor.origin, damage+40);
  246.     
  247.     while (head)
  248.     {
  249.         if (head != ignore)
  250.         {
  251.             if (head.takedamage)
  252.             {
  253.                 org = head.origin + (head.mins + head.maxs)*0.5;
  254.                 points = 0.5*vlen (inflictor.origin - org);
  255.                 if (points < 0)
  256.                     points = 0;
  257.                 points = damage - points;
  258.                 if (head == attacker)
  259.                     points = points * 0.5;
  260.                 if (points > 0)
  261.                 {
  262.                     if (CanDamage (head, inflictor))
  263.                     {     // shambler takes half damage from all explosions
  264.                         if (head.classname == "monster_shambler")                               
  265.                             T_Damage (head, inflictor, attacker, points*0.5);
  266.                         else
  267.                             T_Damage (head, inflictor, attacker, points);
  268.                     }
  269.                 }
  270.             }
  271.         }
  272.         head = head.chain;
  273.     }
  274. };
  275.  
  276. /*
  277. ============
  278. T_BeamDamage
  279. ============
  280. */
  281. void(entity attacker, float damage) T_BeamDamage =
  282. {
  283.     local float       points;
  284.     local entity      head;
  285.     
  286.     head = findradius(attacker.origin, damage+40);
  287.     
  288.     while (head)
  289.     {
  290.         if (head.takedamage)
  291.         {
  292.             points = 0.5*vlen (attacker.origin - head.origin);
  293.             if (points < 0)
  294.                 points = 0;
  295.             points = damage - points;
  296.             if (head == attacker)
  297.                 points = points * 0.5;
  298.             if (points > 0)
  299.             {
  300.                 if (CanDamage (head, attacker))
  301.                 {
  302.                     if (head.classname == "monster_shambler")                               
  303.                         T_Damage (head, attacker, attacker, points*0.5);
  304.                     else
  305.                         T_Damage (head, attacker, attacker, points);
  306.                 }
  307.             }
  308.         }
  309.         head = head.chain;
  310.     }
  311. };
  312.  
  313.